const axios = require('axios');
const fs = require('fs');
const path = require('path');
const { program } = require('commander');
const FormData = require('form-data');


program
 .option('--host <host>', '服务器地址', '127.0.0.1')
 .option('--port <port>', '服务器端口', '8080')
 .option('--user <user>', '用户名', 'zs')
 .option('--pwd <pwd>', '密码', 'ddd')
 .option('--help', '显示帮助信息');


program.parse(process.argv);


const options = program.opts();
let isAuthenticated = false;
let currentUser = '';


if (options.help) {
 console.log(`
  使用方法:
   node client.js login <username> <password>
   node client.js <command> [options]
  
  命令:
   upload <file>  上传本地文件到服务器
   download <file> 下载服务器文件到本地
   delete <file>  删除服务器当前目录的文件
   rename <old> <new> 修改服务器当前目录的文件名
   list      查看服务器当前目录的文件或目录
   mkdir <dir>   在服务器当前目录创建子目录
   rcd <dir>    修改服务器当前目录
   rpwd      打印服务器当前目录的绝对路径
   lcd <dir>    修改本地当前目录
   lpwd      打印本地当前目录的绝对路径
 `);
 process.exit(0);
}


async function authenticate(username, password) {
 try {
  const response = await axios.post(`http://${options.host}:${options.port}/login`, {
   username: username,
   password: password,
  });
  isAuthenticated = true; // 登录成功
  currentUser = username; // 设置当前用户
  console.log(response.data.message);
  console.log(`当前目录: ${response.data.currentDir}`); // 输出当前目录
 } catch (error) {
  if (error.response) {
   console.error('身份验证失败:', error.response.data);
  } else if (error.request) {
   console.error('身份验证失败: 服务器无响应');
  } else {
   console.error('身份验证失败:', error.message);
  }
  process.exit(1);
 }
}


async function handleCommand(command) {
 if (!isAuthenticated) {
  console.error('请先登录。');
  return;
 }


 const args = command.split(' ');
 const cmd = args[0];
 const cmdArgs = args.slice(1);


 switch (cmd) {
  case 'upload':
   const fileName = cmdArgs[0];
   if (!fileName) {
    console.error('请提供要上传的文件名，例如: node client.js upload a.txt');
    return;
   }
   const fileToUpload = path.join(__dirname, fileName);
   if (!fs.existsSync(fileToUpload)) {
    console.error('文件不存在:', fileToUpload);
    return;
   }
   const form = new FormData();
   form.append('file', fs.createReadStream(fileToUpload));
   form.append('username', currentUser); // 添加用户名到表单数据


   try {
    const uploadResponse = await axios.post(`http://${options.host}:${options.port}/upload`, form, {
     headers: {
      ...form.getHeaders(),
     },
    });
    console.log(uploadResponse.data.message);
   } catch (error) {
    console.error('上传失败:', error.response.data);
   }
   break;
  case 'list':
   const listResponse = await axios.get(`http://${options.host}:${options.port}/list/${currentUser}`);
   console.log('当前目录文件:', listResponse.data);
   break;
  case 'delete':
   const nameToDelete = cmdArgs.join(' ');
   const deleteResponse = await axios.delete(`http://${options.host}:${options.port}/delete/${currentUser}/${nameToDelete}`);
   console.log(deleteResponse.data.message);
   break;
  case 'rename':
   const oldName = cmdArgs[0];
   const newName = cmdArgs[1];
   const renameResponse = await axios.post(`http://${options.host}:${options.port}/rename/${currentUser}`, { oldName, newName });
   console.log(renameResponse.data.message);
   break;
  case 'mkdir':
   const dirToCreate = cmdArgs[0];
   if (!dirToCreate) {
    console.error('请提供要创建的目录名，例如: mkdir abc');
    return;
   }
   const mkdirResponse = await axios.post(`http://${options.host}:${options.port}/mkdir/${currentUser}`, { dir: dirToCreate });
   console.log(mkdirResponse.data.message);
   break;
  case 'download':
   const fileToDownload = cmdArgs[0];
   const downloadResponse = await axios.get(`http://${options.host}:${options.port}/download/${currentUser}/${fileToDownload}`, { responseType: 'stream' });
   const writer = fs.createWriteStream(path.join(__dirname, 'downloads', currentUser, fileToDownload));
   downloadResponse.data.pipe(writer);
   writer.on('finish', () => {
    console.log('文件下载成功');
   });
   writer.on('error', (err) => {
    console.error('下载失败:', err);
   });
   break;
  case 'rcd':
   const remoteDir = cmdArgs[0];
   if (!remoteDir) {
    console.error('请提供要切换到的目录，例如: rcd <directory>');
    return;
   }
   const rcdResponse = await axios.post(`http://${options.host}:${options.port}/rcd/${currentUser}`, { dir: remoteDir });
   console.log(rcdResponse.data.message);
   break;
  case 'rpwd':
   const rpwdResponse = await axios.get(`http://${options.host}:${options.port}/rpwd/${currentUser}`);
   console.log(`服务器当前目录: ${rpwdResponse.data.path}`);
   break;
  case 'lcd':
   const localDir = cmdArgs[0];
   if (!localDir) {
    console.error('请提供要切换到的目录，例如: lcd <directory>');
    return;
   }
   try {
    process.chdir(localDir);
    // console.log(`本地当前目录已更改为: ${process.cwd()}`);
    console.log(`本地当前目录已更改成功`);
   } catch (error) {
    console.error('切换目录失败:', error.message);
   }
   break;
  case 'lpwd':
   console.log(`本地当前目录: ${process.cwd()}`);
   break;
  default:
   console.log('未知命令');
 }
}


async function login() {
 const username = options.user;
 const password = options.pwd;


 await authenticate(username, password);


 while (isAuthenticated) {
  const command = await promptUserForCommand();
  await handleCommand(command);
 }
}


function promptUserForCommand() {
 return new Promise((resolve) => {
  const readline = require('readline').createInterface({
   input: process.stdin,
   output: process.stdout
  });


  readline.question('请输入命令: ', (command) => {
   readline.close();
   resolve(command);
  });
 });
}


(async () => {
 // 检查是否有命令行参数提供的用户名和密码，如果有，则使用它们
 if (program.args.length === 0) {
  console.error('请提供登录命令，例如: node client.js login <username> <password>');
  program.help();
 } else if (program.args[0] === 'login' && program.args.length === 3) {
  const username = program.args[1];
  const password = program.args[2];
  await authenticate(username, password);
  while (isAuthenticated) {
   const command = await promptUserForCommand();
   await handleCommand(command);
  }
 } else {
  console.error('无效的命令或参数数量');
  program.help();
 }
})();


// (async () => {
//  await login();
// })();

